import { _decorator, Component, Node, JsonAsset, CameraComponent, screen, input, Input, Vec3, MeshRenderer, geometry, Vec2, isValid, macro, sys, view, EventTouch, resources, Prefab, v3, PhysicsSystem, Quat } from 'cc';
import { PoolManager } from './PoolManager';
import { Builder } from './Builder';
import { NavMesh } from './NavMesh';
import { NavMeshAgent } from './NavMeshAgent';
const { ccclass, property } = _decorator;
const _vector1 = /*@__PURE__*/ new Vec3();
const _vector2 = /*@__PURE__*/ new Vec3();

const ray = new geometry.Ray();
const v3_1: Vec3 = v3();

const timeGap: number = 1;

@ccclass('NavTest')
export default class NavTest extends Component {

    @property(JsonAsset)
    navUrl: JsonAsset = null;
    @property(CameraComponent)
    mainCamera: CameraComponent = null;

    @property({ type: NavMeshAgent })
    agent: NavMeshAgent = null;

    @property(Node)
    target: Node = null;

    @property(MeshRenderer)
    mesh: MeshRenderer = null;

    private targetPos = new Vec3()
    private zone: string = null;
    private distance: number = 0;

    start() {
        //预加载Pointer
        resources.load("Prefabs/Pointer", Prefab, (err, prefab) => {
            PoolManager.ins.setPrefab("Pointer", prefab)
        });

    }

    onEnable() {
        input.on(Input.EventType.TOUCH_END, this.screenTouch, this);
        this.changeScreeen()
        //解析json信息
        let zoneNodes = Builder.buildZoneByJson(this.navUrl.json);
        //区域名字直接使用json文件的名字
        this.zone = this.navUrl.name;
        NavMesh.setZoneData(this.zone, zoneNodes);
    }

    onDisable() {
        NavMesh.clearZoneData(this.zone);
        this.zone = null;
        input.off(Input.EventType.TOUCH_END, this.screenTouch, this);
    }

    changeScreeen() {
        if (sys.isBrowser && sys.isMobile) {
            view.setOrientation(macro.ORIENTATION_LANDSCAPE);
            screen.requestFullScreen()
        }
    }

    screenTouch(event: EventTouch) {
        return;
        let location = event.getLocation();
        let result = this.getTouchModel(location);
        if (result == null) {
            return;
        }
    }

    getTouchModel(location: Vec2) {
        const ray = this.mainCamera.screenPointToRay(location.x, location.y);
        const comps = this.node.parent.getComponentsInChildren(MeshRenderer);
        let mesh: Component = null;
        let distance = Number.MAX_VALUE;
        for (let index = 0; index < comps.length; index++) {
            const element = comps[index];
            if (!isValid(element.node, true) || !element.node.active || !element.model) {
                continue;
            }
            const dis = geometry.intersect.rayModel(ray, element.model, { mode: geometry.ERaycastMode.CLOSEST, doubleSided: false, distance: Number.MAX_VALUE });
            if (dis && dis < distance) {
                distance = dis;
                mesh = element;
            }
        }

        if (mesh == null) return;

        ray.computeHit(this.targetPos, distance);

        this.moveAgent(this.agent, this.targetPos)

        for (var i = this.node.children.length; i >= 0; i--) {
            PoolManager.ins.putNode(this.node.children[i])
        }
    }

    /**
     * @Date: 2022-02-21 14:28:56
     * @LastEditors: iwae
     * @description: 
     * @param {NavMeshAgent} agent 传入Agent脚本
     * @param {Vec3} des 目的地位置
     */

    moveAgent(agent: NavMeshAgent, des: Vec3) {
        let path = this.findPath(this.zone, agent.node.position, des);
        if (path.length > 0) {
            console.error("moveAgent");
            agent.startMove(path);

            for (var i = 0; i < path.length; i++) {
                this.setDebugNode(path[i])
            }
        }
        else {
            console.error("stop");
            agent.stopMove();
        }
    }

    /**
     * @Date: 2022-02-21 14:27:26
     * @LastEditors: iwae
     * @description: 寻找路径
     * @param {string} zoneID 区域ID，这里我们使用的json的文件名作为区域ID
     * @param {Vec3} pos 当前Agent的位置，父节点在中心点，我们使用了local postion
     * @param {Vec3} des 目的地的坐标
     */
    findPath(zoneID: string, pos: Vec3, des: Vec3) {
        _vector1.set(pos);
        const groupId = NavMesh.getGroup(zoneID, _vector1);
        _vector2.set(des);
        const path = NavMesh.findPath(_vector1, _vector2, zoneID, groupId);
        return path;
    }

    /**
     * @Date: 2022-02-21 14:28:28
     * @LastEditors: iwae
     * @description: 
     * @param {Vec3} Pos 生成锚点的位置
     * @param {*} time 生成间隔
     */
    setDebugNode(Pos: Vec3) {
        const cube = PoolManager.ins.getNode("Pointer", this.node)
        cube.setPosition(Pos)
    }

    timer: number = 0;

    protected update(dt: number): void {
        this.timer += dt;

        if (this.timer >= timeGap) {
            //前检测
            Vec3.add(v3_1, this.target.worldPosition, new Vec3(0, -1, 0));
            geometry.Ray.fromPoints(ray, this.target.worldPosition, v3_1);

            this.distance = Number.MAX_VALUE;
            const dis = geometry.intersect.rayModel(ray, this.mesh.model, { mode: geometry.ERaycastMode.CLOSEST, doubleSided: false, distance: Number.MAX_VALUE });

            if (dis && dis < Number.MAX_VALUE) {
                this.distance = dis;
            }

            for (var i = this.node.children.length; i >= 0; i--) {
                PoolManager.ins.putNode(this.node.children[i])
            }

            ray.computeHit(this.targetPos, this.distance);
            this.moveAgent(this.agent, this.targetPos)
            this.timer = 0;
        }
    }
}